

#ifndef SAR_SYSTEM_VM_INSTRUCTION_H
#define SAR_SYSTEM_VM_INSTRUCTION_H

#include "state.h"

#include <kernel/kernel.h>

typedef void (*vm_CallbackABC) (vm_State *, int, int, int);
typedef void (*vm_CallbackAxB) (vm_State *, int, int);

typedef union CALLBACK {
	vm_CallbackABC ABC;
	vm_CallbackAxB ABx;
} vm_Callback;

typedef char vm_InstructionFormat;

#define VM_INSTRUCTION_ABC 0
#define VM_INSTRUCTION_ABx 1

#define VM_INSTRUCTION_OPMASK 0x2F
#define VM_INSTRUCTION_AMASK 0x2FFc0
#define VM_INSTRUCTION_BMASK 0x7FC000
#define VM_INSTRUCTION_CMASK 0xFF800000
#define VM_INSTRUCTION_BxMASK 0xFFFFC000

typedef struct INSTRUCTION {
	char *Mnemonic;
	vm_InstructionFormat Format;
	vm_Callback Callback;
} vm_Instruction;

vm_Instruction *vm_instruction_mnemonic (const char *_mnemonic);
vm_Instruction *vm_instruction_opcode (char _opcode);

#define vm_instruction_getop(w) (w & VM_INSTRUCTION_OPMASK)
#define vm_instruction_getA(w) (w & VM_INSTRUCTION_AMASK >> 6)
#define vm_instruction_getB(w) (w & VM_INSTRUCTION_BMASK >> 14)
#define vm_instruction_getC(w) (w >> 25)
#define vm_instruction_getBx(w) (w >> 14)

#endif

